package com.ruoyi.web.controller.system;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.business.domain.*;
import com.ruoyi.business.domain.vo.HIKUserFace;
import com.ruoyi.business.service.IRecordNoticeService;
import com.ruoyi.business.service.IRecordPictureService;
import com.ruoyi.business.service.IWxFaceDeviceService;
import com.ruoyi.business.service.IWxUserFaceService;
import com.ruoyi.business.service.impl.HikVisionServiceImpl;
import com.ruoyi.business.vo.*;
import com.ruoyi.business.vo.ResponseStatus;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.dto.*;
import com.ruoyi.framework.config.ServerConfig;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
public class DeviceConfigController {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private IRecordPictureService recordPictureService;

    @Autowired
    private IRecordNoticeService recordNoticeService;

    @Autowired
    private IWxUserFaceService wxUserFaceService;

    @Autowired
    private IWxFaceDeviceService wxFaceDeviceService;

    public static final Logger log = LoggerFactory.getLogger(DeviceConfigController.class);

    @GetMapping("/clear/{sn}")
    public boolean clear(@PathVariable String sn) {
        List<HandleAddPersonInfo> deviceJobs;

        if (redisCache.redisTemplate.hasKey("FACE_DEVICE_JOBS")) {
            deviceJobs = redisCache.getCacheList("FACE_DEVICE_JOBS");

            if (deviceJobs == null || deviceJobs.isEmpty()) {
                deviceJobs = new ArrayList<>();
            }
        } else {
            deviceJobs = new ArrayList<>();
        }
        HandleAddPersonInfo clear = new HandleAddPersonInfo();
        clear.setSn(sn);
        clear.setId("clearAll");
        clear.setCmd("clearAll");
        clear.setClearRecord(false);
        deviceJobs.add(clear);
        System.out.println("设置设备任务--清除所有");
        redisCache.deleteObject("FACE_DEVICE_JOBS");
        if (!deviceJobs.isEmpty()) {
            redisCache.setCacheList("FACE_DEVICE_JOBS", deviceJobs);
        }
        return true;
    }

    @PostMapping("/person/cmd")
    public DataAcceptDTO personCmd(@RequestBody DeviceConfigDTO deviceConfigDTO) {

        DataAcceptDTO<List<HandleAddPersonInfo>> dataAcceptDTO = new DataAcceptDTO<>();
        dataAcceptDTO.setSuccess(true);
        dataAcceptDTO.setSn(deviceConfigDTO.getSn());

        if (StringUtils.isEmpty(deviceConfigDTO.getSn())) {
            return dataAcceptDTO;
        }

        redisCache.setCacheObject("SN_ONLINE_" + deviceConfigDTO.getSn(), true, 60 , TimeUnit.SECONDS);
        redisCache.setCacheObject("SN_CONFIG_" + deviceConfigDTO.getSn(), deviceConfigDTO);

        Boolean hasKey = redisCache.redisTemplate.hasKey("FACE_DEVICE_JOBS");
        if (!hasKey) {
            dataAcceptDTO.setData(new ArrayList<>());
            return dataAcceptDTO;
        }

        List<HandleAddPersonInfo> face_device_jobs = redisCache.getCacheList("FACE_DEVICE_JOBS");
        if (face_device_jobs.isEmpty()) {
            dataAcceptDTO.setData(new ArrayList<>());
            return dataAcceptDTO;
        }

        List<HandleAddPersonInfo> collect = face_device_jobs.stream().filter(item -> item.getSn().equals(deviceConfigDTO.getSn())).collect(Collectors.toList());
        dataAcceptDTO.setData(collect);
        return dataAcceptDTO;
    }

    @PostMapping("/person/result")
    public Object personResultCmd(@RequestBody DataAcceptDTO<List<PersonCmdResultDTO>> dataAcceptDTO) {
        System.out.println("人员操作回复:");
        System.out.println("dataAcceptDTO:" + dataAcceptDTO.toString());
        System.out.println("SN:" + dataAcceptDTO.getSn());
        System.out.println("DATA:" + dataAcceptDTO.getData());
        HashMap<String, String> map = new HashMap<>();

        if (!dataAcceptDTO.getSuccess()) {
            map.put("success", "true");
            return map;
        }

        List<PersonCmdResultDTO> data = dataAcceptDTO.getData();
        if (data == null || data.isEmpty()) {
            map.put("success", "true");
            return map;
        }
        List<HandleAddPersonInfo> face_device_jobs = redisCache.getCacheList("FACE_DEVICE_JOBS");
        if (face_device_jobs == null || face_device_jobs.isEmpty()) {
            map.put("success", "true");
            return map;
        }
        data.forEach(item -> {
            if (face_device_jobs != null && !face_device_jobs.isEmpty()) {
                for (HandleAddPersonInfo job : face_device_jobs) {
                    if (item.getCmd().equals(job.getCmd()) && item.getId().equals(job.getId())) {
                        WxUserFace wxUserFace = new WxUserFace();
                        wxUserFace.setBindingDispatchUuids(item.getId());
                        List<WxUserFace> wxUserFaces = wxUserFaceService.selectWxUserFaceList(wxUserFace);
                        if (wxUserFaces != null && !wxUserFaces.isEmpty()) {
                            wxUserFaces.forEach(wxUserFace1 -> {
                                wxUserFace1.setDispatchStatus("2");
                                wxUserFace1.setDispatchDate(DateUtils.getNowDate());
                                wxUserFaceService.updateWxUserFace(wxUserFace1);
                            });
                        }
                        face_device_jobs.remove(job);
                        redisCache.deleteObject("FACE_DEVICE_JOBS");
                        if (!face_device_jobs.isEmpty()) {
                            redisCache.setCacheList("FACE_DEVICE_JOBS", face_device_jobs);
                        }
                        break;
                    }
                }
            }
        });
        map.put("success", "true");
        return map;
    }

    @PostMapping("/record/picture")
    public Object recordPicture(MultipartFile file, @RequestHeader("sn") String sn, @RequestHeader("id") String id, @RequestHeader("regTime") String regTime, @RequestHeader("type") String type) {
        HashMap<String, String> map = new HashMap<>();
        try {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url = serverConfig.getUrl() + fileName;
//            url = WeAppConfig.IMAGE_HOST + url;
            RecordPicture recordPicture = new RecordPicture();
            recordPicture.setId(id);
            recordPicture.setSn(sn);
//            recordPicture.setName(name);
            recordPicture.setRegTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", regTime));
            recordPicture.setType(type);
            recordPicture.setRemark(url);
            recordPictureService.insertRecordPicture(recordPicture);
            map.put("success", "true");
            map.put("regPicture", url);
        } catch (Exception e) {
            System.out.println("上传文件失败");
        }
        return map;
    }

    @PostMapping("/record/notice")
    public Object recordNotice(@RequestBody DataAcceptDTO<List<RecordInfoDTO>> dtoDataAcceptDTO) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("success", true);
        List<RecordInfoDTO> data = dtoDataAcceptDTO.getData();
        if (data == null || data.isEmpty()) {
            return map;
        }

        data.forEach(item -> {
            RecordNotice recordNotice = new RecordNotice();
            recordNotice.setId(item.getId());
            recordNotice.setBodyTemperature(item.getBodyTemperature());
            recordNotice.setIcCard(item.getIcCard());
            recordNotice.setIdCard(item.getIdCard());
            recordNotice.setGateDirection(item.getGateDirection());
            recordNotice.setRegPicture(item.getRegPicture());
            recordNotice.setRegType(item.getRegType());
            recordNotice.setName(item.getName());
            recordNotice.setRegTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", item.getRegTime()));
            recordNoticeService.insertRecordNotice(recordNotice);
        });
        return map;
    }

    @PostMapping("/setting/cmd")
    public Map settingCmd(@RequestBody SettingConfigDTO settingConfigDTO) {
        HashMap<String, Object> resMap = new HashMap<>();
        resMap.put("success", true);
        resMap.put("msg", true);

        List<HandleSettingInfo> list = new ArrayList<>();
        Boolean hasKey = redisCache.redisTemplate.hasKey("SETTING_JOBS_" + settingConfigDTO.getSn());
        if (!hasKey) {
            list = new ArrayList<>();
            resMap.put("data", list);
            return resMap;
        }

        List<HandleSettingInfo> setting_jobs = redisCache.getCacheList("SETTING_JOBS_" + settingConfigDTO.getSn());
        if (!setting_jobs.isEmpty()) {
            list = setting_jobs;
        }
        resMap.put("data", list);
        return resMap;
    }

    @PostMapping("/setting/result")
    public Map settingResult(@RequestBody DataAcceptDTO<List<HandleSettingInfo>> dto) {
        Map<String, Object> resMap = new HashMap<>();
        try {
            if (dto.getSuccess()) {
                redisCache.redisTemplate.delete("SETTING_JOBS_" + dto.getSn());
                List<HandleSettingInfo> data = dto.getData();
                data.forEach(item -> {
                    if (item.getCmd().equals("openGate")) {
                        redisCache.setCacheObject("OPEN_GATE_" + dto.getSn(), true);
                    }
                });
                resMap.put("success", true);
            }
        } catch (Exception e) {
            resMap.put("success", false);
        }
        return resMap;
    }


    @PostMapping("/hikRecord")
    @Transactional
    public Object hikRecord(MultipartFile Picture, @RequestParam("event_log") String eventLog) {
        EventNotificationAlert eventNotificationAlert = new EventNotificationAlert();

        JSONObject eventInfo = JSONObject.parseObject(eventLog, JSONObject.class);
        JSONObject accessControllerEvent =  (JSONObject) eventInfo.get("AccessControllerEvent");
        String deviceId = (String) eventInfo.get("deviceID");
        String name = (String) accessControllerEvent.get("name");
        String employeeNoString = (String) accessControllerEvent.get("employeeNoString");

        if (employeeNoString == null) {
            return eventNotificationAlert;
        }
        String dateTime = (String) eventInfo.get("dateTime");
        String currentVerifyMode = (String) accessControllerEvent.get("currentVerifyMode");

        try {
//             上传文件路径
            if (Picture != null) {
                String filePath = RuoYiConfig.getUploadPath();
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, Picture);
                String url = serverConfig.getUrl() + fileName;
//            url = WeAppConfig.IMAGE_HOST + url;
                RecordPicture recordPicture = new RecordPicture();
                recordPicture.setId(employeeNoString);
                recordPicture.setSn(deviceId);
                recordPicture.setName(name);
                recordPicture.setRegTime(DateUtils.getNowDate());
                recordPicture.setType(currentVerifyMode);
                recordPicture.setRemark(url);
                recordPictureService.insertRecordPicture(recordPicture);
                RecordNotice recordNotice = new RecordNotice();
                recordNotice.setId(employeeNoString);
                recordNotice.setRegType(currentVerifyMode);
                recordNotice.setName(name);
                recordNotice.setRegTime(DateUtils.getNowDate());
                recordNoticeService.insertRecordNotice(recordNotice);

                eventNotificationAlert.setChannelID((Integer)eventInfo.get("channelID"));
                eventNotificationAlert.setActivePostCount((Integer)eventInfo.get("activePostCount"));
                eventNotificationAlert.setChannelName("通道1");
                eventNotificationAlert.setEventDescription("人脸识别事件");
                eventNotificationAlert.setEventType(currentVerifyMode);
                eventNotificationAlert.setDateTime(DateUtils.parseDate(dateTime));

                WxFaceDevice wxFaceDevice = new WxFaceDevice();
                wxFaceDevice.setHikDeviceNum(deviceId);
                List<WxFaceDevice> wxFaceDevices = wxFaceDeviceService.selectWxFaceDeviceList(wxFaceDevice);
                if (wxFaceDevices.size() > 0) {
                    eventNotificationAlert.setDevIndex(wxFaceDevices.get(0).getHikDeviceIndex());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("海康设备推送数据保存异常");
        }
        return eventNotificationAlert;
    }

}
